/**
 * 树模式-左侧的树组件
 */

import React from 'react';
import { Tree } from '@teamix/ui';
import { YunxiaoIcon } from '@alife/devops-ui';
import { navigate } from 'utils/router';
import utils from 'utils';
import AddOrUploadFile from './addOrUploadFile';
import FileIcon from 'components/fileIcon';
import TreeSkeleton from './components/skeleton/leftTreeSkeleton';
import intl from '../../../../../../../../locale';

const { pathResource, resourceSubject } = window.FORCE;
const TreeNode = Tree.Node;

export default class TreeLeft extends React.Component {
  // confirmResult 选择treeItem的弹窗结果, isTreeItemSelected 是否是点击 treeItem
  confirmResult = true;

  isTreeItemSelected = false;

  onTreeLoadData = (treeNode) => {
    if (this.isTreeItemSelected) {
      this.isTreeItemSelected = false;
      if (!this.confirmResult) {
        return null;
      }
    } else if (this.props.selectedType === 'edit' || this.props.selectedType === 'new') {
      // 点击文件夹前面的箭头
      const result = window.confirm(
        this.props.selectedType === 'edit'
          ? intl.get({
              id: 'code-assets.containers.content.treeLeft.YouAreEditingTheFile',
              defaultMessage: '您正在编辑文件，是否确认离开？',
            })
          : intl.get({
              id: 'code-assets.containers.content.treeLeft.YouAreCreatingANew',
              defaultMessage: '您正在新建文件，是否确认离开？',
            }),
      );
      if (!result) {
        return false;
      } else {
        window.onbeforeunload = null; // 清空阻止跳转事件
      }
    }

    // 当为 submodule 时，不需调接口
    if (treeNode.props.resourceType === 'commit') {
      return null;
    }

    const key = treeNode.props.eventKey;
    // 点根节点时
    if (key === 'root') {
      navigate(
        `/${pathResource.fullPath}/tree/${utils.revisionEncodeURI(resourceSubject.revision)}/`,
      );
      this.props.updateSetSelectedType({
        resourceSubject: {
          subject: 'tree',
          path: '',
        },
      });

      this.rewriteDocTitle('', resourceSubject.revision);
      return new Promise((resolve) => {
        this.props.getExpandedTreeData('', resolve);
      });
    }
    if (treeNode.props.resourceType === 'tree') {
      const curPath = `/${pathResource.fullPath}/tree/${utils.revisionEncodeURI(
        resourceSubject.revision,
      )}/${utils.filepathEncodeURI(key)}`;
      // 路径相同不触发操作
      if (window.location.pathname === curPath) {
        return Promise.resolve();
      }
      navigate(curPath);
      this.props.updateSetSelectedType({
        resourceSubject: {
          subject: 'tree',
          path: key,
        },
      });
    }
    this.rewriteDocTitle(key, resourceSubject.revision);
    return new Promise((resolve) => {
      // 点击文件不需要请求树
      if (treeNode.props.resourceType === 'tree') {
        this.props.getExpandedTreeData(key, resolve);
      } else {
        resolve();
      }
    });
  };

  onTreeItemSelect = (selectedKeys, e) => {
    try {
      e.node.itemNode.querySelector('.yx-tree-switcher').click();
    } catch (error) {
      console.error(error);
    }
    const { submodules } = this.props;
    const { isLeaf, eventKey: key } = e.node.props;

    // 点击已选中的item
    if (!selectedKeys.length) {
      return false;
    }

    this.isTreeItemSelected = true;
    // 当处于编辑或新建页，点击左侧树时，进行二次确认
    if (this.props.selectedType === 'edit' || this.props.selectedType === 'new') {
      this.confirmResult = window.confirm(
        this.props.selectedType === 'edit'
          ? intl.get({
              id: 'code-assets.containers.content.treeLeft.YouAreEditingTheFile',
              defaultMessage: '您正在编辑文件，是否确认离开？',
            })
          : intl.get({
              id: 'code-assets.containers.content.treeLeft.YouAreCreatingANew',
              defaultMessage: '您正在新建文件，是否确认离开？',
            }),
      );
      if (!this.confirmResult) {
        return false;
      } else {
        window.onbeforeunload = null; // 清空阻止跳转事件
      }
    }

    // TODO 如果是文件，则跳转；否则展开子树 aisc不支持？
    if (isLeaf) {
      const path = selectedKeys[0];

      // resourceType === 'commit' 为 submodule
      if (e.node.props.resourceType === 'commit') {
        // 如果path有对应的submodule，则跳转submodule
        const submodule = submodules && submodules.find((item) => item.path === path);
        if (submodule) {
          window.location = submodule.http_homepage_url;
        }
      } else {
        const pathPrefix = `/${pathResource.fullPath}/blob/${utils.revisionEncodeURI(
          resourceSubject.revision,
        )}/`;
        this.jumpTo(pathPrefix + utils.revisionEncodeURI(path), key, path);
      }
    }
  };

  rewriteDocTitle = (key, revision) => {
    const projectName =
      pathResource.fullPath && pathResource.fullPath.split('/')
        ? pathResource.fullPath.split('/')[1]
        : '';
    document.title = key
      ? [
          key,
          revision,
          projectName,
          intl.get({
            id: 'code-assets.containers.content.treeLeft.YunxiaoCodeup',
            defaultMessage: '云效 Codeup',
          }),
        ].join(' · ')
      : [
          revision,
          projectName,
          intl.get({
            id: 'code-assets.containers.content.treeLeft.YunxiaoCodeup',
            defaultMessage: '云效 Codeup',
          }),
        ].join(' · ');
  };

  jumpTo = (path, key, filepath) => {
    const curPath = utils.filepathEncodeURI(path);
    if (curPath === window.location.pathname) {
      return;
    }
    navigate(curPath);
    this.props.updateSetSelectedType({
      resourceSubject: {
        subject: 'blob',
        path: filepath || '',
      },
    });

    this.rewriteDocTitle(key, resourceSubject.revision);
  };

  updateExpandKeys = (keys) => {
    this.props.updateData({
      defaultExpandedKeys: keys,
    });
  };

  goNew = () => {
    const defaultBranch = window.FORCE.pathResource.defaultBranch || 'master';
    navigate(
      `/${pathResource.fullPath}/new/${defaultBranch}/${utils.revisionEncodeURI(
        resourceSubject.revision,
      )}?file_name=README.md`,
    );

    this.props.updateSetSelectedType({
      resourceSubject: {
        subject: 'blob',
        path: '',
      },
    });
  };

  setLabbelWidth = (e, item) => {
    // TODO item.label
    const { currentTarget } = e;
    if (item.type !== 'tree') {
      return;
    }
    // const { left } = currentTarget.getBoundingClientRect();
    const { projectNav } = this.props;
    let width = 300;
    if (projectNav) {
      const navWidth = projectNav.getBoundingClientRect().width;
      width = navWidth || 300;
    }
    // 300为左侧树宽 20为文件夹icon宽 29为右侧hover时出现+的预留距离 12为树整体的padding
    const { isSidebarStick } = window.localStorage;
    const isStick = isSidebarStick === 'true';
    currentTarget.style.maxWidth = isStick ? `${width - 12 - 29}px` : `${width - 12 - 29 + 156}px`;
    currentTarget.style.position = 'absolute';
    currentTarget.querySelector('.name').style.maxWidth = `${width - 20 - 29 - 12}px`;
  };

  resetLabbelWidth = (e, item) => {
    if (item.type !== 'tree') {
      return;
    }
    e.currentTarget.style.maxWidth = 'none';
    e.currentTarget.style.position = 'relative';
    e.currentTarget.querySelector('.name').style.maxWidth = 'none';
    const { onUploadDialogClose } = this.props;
    onUploadDialogClose && onUploadDialogClose();
  };

  render() {
    const loop = (data) =>
      [...data.filter((v) => v.type === 'tree'), ...data.filter((v) => v.type !== 'tree')].map(
        (item) => {
          const { id, name, type } = item.label ? item.label : item;
          return (
            <TreeNode
              label={
                <span
                  onMouseEnter={(e) => {
                    this.setLabbelWidth(e, item);
                  }}
                  onMouseLeave={(e) => {
                    this.resetLabbelWidth(e, item);
                  }}
                  className="label-content"
                >
                  {type !== 'commit' ? (
                    <React.Fragment>
                      {type === 'tree' ? (
                        <YunxiaoIcon type="folder-line" className="file-icon" />
                      ) : (
                        // <YunxiaoIcon type={'folder-line'} className="file-icon" />
                        <FileIcon className="file-icon" fileName={name} />
                      )}
                    </React.Fragment>
                  ) : (
                    <i className="fa fa-archive" />
                  )}{' '}
                  <span className="name one-line-ellipsis" title={name}>
                    {name}
                  </span>
                  {type === 'tree' && (
                    <span className="add-upload-file-btn" onClick={(e) => e.stopPropagation()}>
                      <AddOrUploadFile followTrigger size="small" treePath={id} {...this.props} />
                    </span>
                  )}
                </span>
              }
              key={id}
              isLeaf={type !== 'tree'}
              resourceType={type}
              className={type === 'tree' ? 'tree-class' : 'leaf-class'}
            >
              {item.children && loop(item.children)}
            </TreeNode>
          );
        },
      );

    const { treeData, defaultExpandedKeys, selectedKeys, isInittingLeftTree } = this.props;
    const treeNodeName =
      pathResource.fullPath.split('/')[pathResource.fullPath.split('/').length - 1];

    if (isInittingLeftTree) {
      return <TreeSkeleton />;
    }

    return (
      <React.Fragment>
        <Tree
          expandedKeys={defaultExpandedKeys}
          selectedKeys={selectedKeys}
          loadData={this.onTreeLoadData}
          onSelect={this.onTreeItemSelect}
          onExpand={this.updateExpandKeys}
          className="file-tree"
          autoExpandParent={false}
          isLabelBlock
          // useVirtual
          // //  https://yuque.antfin-inc.com/docs/share/cb036dc8-b1f7-4689-9e74-5a304e940a13# 多文件测试
          // style={{
          //   display: 'inline-block',
          //   minWidth: '100%',
          //   maxHeight: 'calc(100vh - 145px)',
          //   overflow: 'auto',
          // }}
          animation={false}
        >
          <TreeNode label={<span title={treeNodeName}>{treeNodeName}</span>} key="root">
            {loop(treeData)}
          </TreeNode>
        </Tree>
      </React.Fragment>
    );
  }
}
